/**
 * @class
 * @class this
 * @constructor
 * @param { object } options
 *
 * @method format(value) value:需要格式传入的值
 *
 * @method getRawValue(value) Vlue: 获取格式的值
 */

// class formatterBase {
//   constructor
// }

export default class NumeralFormatter {
  groupStyle = {
    thousand: 'thousand',
    lakh: 'lakh',
    wan: 'wan',
    none: 'none'
  }
  constructor (options = {}) {
    const {
      numeralDecimalMark,
      numeralIntegerScale,
      numeralDecimalScale,
      numeralThousandsGroupStyle,
      numeralPositiveOnly,
      stripLeadingZeroes,
      prefix,
      signBeforePrefix,
      delimiter
    } = options
    this.numeralDecimalMark = numeralDecimalMark || '.'
    this.numeralIntegerScale = numeralIntegerScale > 0 ? numeralIntegerScale : 0
    this.numeralDecimalScale = numeralDecimalScale >= 0 ? numeralDecimalScale : 2
    this.numeralThousandsGroupStyle = numeralThousandsGroupStyle || this.groupStyle.thousand
    this.numeralPositiveOnly = !!numeralPositiveOnly
    this.stripLeadingZeroes = stripLeadingZeroes !== false
    this.prefix = prefix || prefix === '' ? prefix : ''
    this.signBeforePrefix = !!signBeforePrefix
    this.delimiter = delimiter || delimiter === '' ? delimiter : ','
    this.delimiterRE = delimiter ? new RegExp('\\' + delimiter, 'g') : ''
  }

  getRawValue (value) {
    return value.replace(this.delimiterRE, '').replace(this.numeralDecimalMark, '.')
  }
  format (value) {
    const owner = this
    let parts
    let partSign
    let partSignAndPrefix
    let partInteger
    let partDecimal = ''

    // strip alphabet letters
    value = value
      .replace(/[A-Za-z]/g, '')
      // replace the first decimal mark with reserved placeholder
      .replace(owner.numeralDecimalMark, 'M')

      // strip non numeric letters except minus and "M"
      // this is to ensure prefix has been stripped
      .replace(/[^\dM-]/g, '')

      // replace the leading minus with reserved placeholder
      // .replace(/^\-/, 'N')
      .replace(/^-/, 'N')

      // strip the other minus sign (if present)
      // .replace(/\-/g, '')
      .replace(/-/g, '')

      // replace the minus sign (if present)
      .replace('N', owner.numeralPositiveOnly ? '' : '-')

      // replace decimal mark
      .replace('M', owner.numeralDecimalMark)

    // strip any leading zeros
    if (owner.stripLeadingZeroes) {
      value = value.replace(/^(-)?0+(?=\d)/, '$1')
    }

    partSign = value.slice(0, 1) === '-' ? '-' : ''
    if (typeof owner.prefix !== 'undefined') {
      if (owner.signBeforePrefix) {
        partSignAndPrefix = partSign + owner.prefix
      } else {
        partSignAndPrefix = owner.prefix + partSign
      }
    } else {
      partSignAndPrefix = partSign
    }

    partInteger = value

    if (value.indexOf(owner.numeralDecimalMark) >= 0) {
      parts = value.split(owner.numeralDecimalMark)
      partInteger = parts[0]
      partDecimal = owner.numeralDecimalMark + parts[1].slice(0, owner.numeralDecimalScale)
    }

    if (partSign === '-') {
      partInteger = partInteger.slice(1)
    }

    if (owner.numeralIntegerScale > 0) {
      partInteger = partInteger.slice(0, owner.numeralIntegerScale)
    }

    switch (owner.numeralThousandsGroupStyle) {
      case this.groupStyle.lakh:
        partInteger = partInteger.replace(/(\d)(?=(\d\d)+\d$)/g, '$1' + owner.delimiter)

        break

      case this.groupStyle.wan:
        partInteger = partInteger.replace(/(\d)(?=(\d{4})+$)/g, '$1' + owner.delimiter)

        break

      case this.groupStyle.thousand:
        partInteger = partInteger.replace(/(\d)(?=(\d{3})+$)/g, '$1' + owner.delimiter)

        break
    }

    return partSignAndPrefix + partInteger.toString() + (owner.numeralDecimalScale > 0 ? partDecimal.toString() : '')
  }
}
